home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- # DiskDrake
- # Copyright (C) 1999 MandrakeSoft (pixel@linux-mandrake.com)
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2, or (at your option)
- # any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- # This is mainly a perl rewrite of the work of Andrew Clausen (libresize)
-
- package resize_fat::main;
-
-
-
-
- use log;
- use common qw(:common :system :constant);
- use resize_fat::boot_sector;
- use resize_fat::info_sector;
- use resize_fat::directory;
- use resize_fat::io;
- use resize_fat::fat;
- use resize_fat::any;
-
-
- 1;
-
-
- sub new($$$) {
- my ($type, $device, $fs_name) = @_;
- my $fs = { device => $device, fs_name => $fs_name } ;
-
- resize_fat::io::open($fs);
- resize_fat::boot_sector::read($fs);
- $resize_fat::isFAT32 and eval { resize_fat::info_sector::read($fs) };
- resize_fat::fat::read($fs);
- resize_fat::any::flag_clusters($fs);
-
- bless $fs, $type;
- }
-
- sub DESTROY { resize_fat::c_rewritten::free_all() }
-
-
-
-
- sub copy_clusters {
- my ($fs, $cluster) = @_;
- my @buffer;
- my $flush = sub {
- while (@buffer) {
- my $cluster = shift @buffer;
- resize_fat::io::write_cluster($fs, $cluster, shift @buffer);
- }
- };
- for (; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::FILE or next;
- push @buffer,
- resize_fat::c_rewritten::fat_remap($cluster),
- resize_fat::io::read_cluster($fs, $cluster);
- @buffer > 50 and &$flush();
- }
- &$flush();
- }
-
-
- sub construct_dir_tree {
- my ($fs) = @_;
-
- if ($resize_fat::isFAT32) {
-
-
- resize_fat::c_rewritten::set_flag($fs->{fat32_root_dir_cluster}, $resize_fat::any::FREE);
- }
-
- for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
- resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::DIRECTORY or next;
-
- resize_fat::io::write_cluster($fs,
- resize_fat::c_rewritten::fat_remap($cluster),
- resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
- }
-
- sync();
-
-
-
- #
-
-
-
- if ($resize_fat::isFAT32) {
- my $cluster = $fs->{fat32_root_dir_cluster};
-
- resize_fat::io::write_cluster($fs,
- resize_fat::c_rewritten::fat_remap($cluster),
- resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
- } else {
- resize_fat::io::write($fs, $fs->{root_dir_offset}, $fs->{root_dir_size},
- resize_fat::directory::remap($fs, resize_fat::io::read($fs, $fs->{root_dir_offset}, $fs->{root_dir_size})));
- }
- }
-
- sub min_size($) { &resize_fat::any::min_size }
- sub max_size($) { &resize_fat::any::max_size }
-
-
-
-
-
- sub resize {
- my ($fs, $size) = @_;
-
- my ($min, $max) = (min_size($fs), max_size($fs));
-
-
- $size += $min if $size =~ /^\+/;
-
- $size >= $min or die "Minimum filesystem size is $min sectors";
- $size <= $max or die "Maximum filesystem size is $max sectors";
-
- log::l("resize_fat: Partition size will be ", $size * $SECTORSIZE >> 20, "Mb (well exactly ${size} sectors)");
-
- my $new_data_size = $size * $SECTORSIZE - $fs->{cluster_offset};
- my $new_nb_clusters = divide($new_data_size, $fs->{cluster_size});
-
- log::l("resize_fat: Allocating new clusters");
- resize_fat::fat::allocate_remap($fs, $new_nb_clusters);
-
- log::l("resize_fat: Copying files");
- copy_clusters($fs, $new_nb_clusters);
-
- log::l("resize_fat: Copying directories");
- construct_dir_tree($fs);
-
- log::l("Writing new FAT...");
- resize_fat::fat::update($fs);
- resize_fat::fat::write($fs);
-
- $fs->{nb_sectors} = $size;
- $fs->{nb_clusters} = $new_nb_clusters;
- $fs->{clusters}{count}->{free} =
- $fs->{nb_clusters} - $fs->{clusters}{count}->{used} - $fs->{clusters}->{count}->{bad} - 2;
-
- $fs->{system_id} = 'was here!';
- $fs->{small_nb_sectors} = 0;
- $fs->{big_nb_sectors} = $size;
-
- log::l("resize_fat: Writing new boot sector...");
-
- resize_fat::boot_sector::write($fs);
-
- $resize_fat::isFAT32 and eval { resize_fat::info_sector::write($fs) };
-
- sync();
- close $fs->{fd};
- log::l("resize_fat: done");
- }
-
-